/* 
 *	Copyright (C) 2009-2010 miaohua
 *	http://code.google.com/p/lrcshower/
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */
#pragma once

#include <map>
#include <string>
#include <vector>
#include <tchar.h>
#include "TypeDef.h"
#include "LrcShow.h"

// Lrc show time compare function object
struct LrcTimeCmp
{
    bool operator()(OneLineLrc & l, OneLineLrc & r)
    {
         return l.m_Time < r.m_Time;
    }
};

struct AddOffset
{
    int Offset;
    AddOffset(int offset):Offset(offset){}
    OneLineLrc operator()(OneLineLrc & One)
    {
         One.m_Time += Offset;
         if( One.m_Time < 0 ) One.m_Time = 0;
         return One;
    }
};

// Key words of lrc file
static tstring Keywords[]=
{   _T("ar"),            //artist
    _T("ti"),            //title
    _T("al"),            //album
    _T("by"),            //the author of the lrc file
    _T("offset"),        //the time offset, in misecond unit, plus means moving all timestamp forward, or moving backword
    _T("key")            //encrypt string, added by lrc editor
};

enum KeywordsName{ARTIST, TITLE, ALBUM, BY, OFFSET, KEY};

class CLrcAnalyzer;
typedef  bool (CLrcAnalyzer::*KeywordProc)(const tstring &);

enum LrcParseErr{ NoErr,          // No Error
                  FileSame,       // Parse the latest two files are same
                  FileNotExist,   // Lrc file doesn't exist
                  OpenFileErr };  // Open lrc file error

// Lrc file analyze
// ClrcAnalyzer can only parse the lrc file as followings:
// [0:31] aaaaaaaaaa
// [1.52] aaaaaaaaaa
class CLrcAnalyzer
{
public:
     CLrcAnalyzer();
     // Analyze the whole lrc file
     bool AnalyzeLrcFile(const tstring & FullPath, bool Force=false);
     // Get the lrc buffer
     const LrcBuf * GetLrcBuf()const { return &m_LrcBuf; }
	 // Get the maximum length lrc line's index
	 int GetMaxLenIdx()const { return m_MaxLenIdx; }
     // Get last parse error
     LrcParseErr GetLastParseErr()const { return m_LastParseErr; }
     

     // Set offset for key word offset
     bool SetOffset(const tstring & Offset);
     // Set  title for key word ti
     bool SetTitle(const tstring & Title);
     // Set song's duration
     void SetDuration(long long Duration);

private:
     // Helper functions
     // Analyze one lrc line
     bool AnalyseOneLine(const tstring & Line);
     // Check wether it is a key word(key words are defined in array Keywords)
     bool CheckKeyWord(const tstring & Word);
     // Calculate the duration of every line     
     void CalcDuration();
     // Convert a lrc format time( like [02:48.72] ) string to integer type(in misecond unit)
     int GetTime(const tstring & Time);

     tstring m_LrcFileFullPath;                     // Full path of the lrc file
     LrcBuf  m_LrcBuf;                              // Lrc buffer containing the lrc parser result
     std::map<tstring, KeywordProc> m_KeywordsProc; // Lrc file key word process map

     LrcParseErr m_LastParseErr;                    // The error code for latest parse
     int m_TimeOffset;                              // Time offset for the whole song
	 int m_MaxLenIdx;                               // Index of one line lrc which has maximum length
     long long m_Duration;                          // Media file's duration
     tstring m_Name;                                // Media file's name

};